﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfImageDuplicates
{
    public partial class CompareImagesView : UserControl
    {
        public event EventHandler<ObjectEventArgs<FileImageViewModel, FileImageViewModel>> Duplicate;
        public event EventHandler<ObjectEventArgs<FileImageViewModel, FileImageViewModel>> AllDuplicates;
        public event EventHandler<ObjectEventArgs<FileImageViewModel, FileImageViewModel>> NotDuplicate;

        public static readonly DependencyProperty FileImageViewModel1Property =
            DependencyProperty.Register("FileImageViewModel1", typeof(FileImageViewModel), typeof(CompareImagesView), new PropertyMetadata(null, OnFileImageViewModel1PropertyChanged));

        public static readonly DependencyProperty FileImageViewModel2Property =
            DependencyProperty.Register("FileImageViewModel2", typeof(FileImageViewModel), typeof(CompareImagesView), new PropertyMetadata(null, OnFileImageViewModel2PropertyChanged));

        public FileImageViewModel FileImageViewModel1
        {
            get { return (FileImageViewModel)GetValue(FileImageViewModel1Property); }
            set { SetValue(FileImageViewModel1Property, value); }
        }

        public FileImageViewModel FileImageViewModel2
        {
            get { return (FileImageViewModel)GetValue(FileImageViewModel2Property); }
            set { SetValue(FileImageViewModel2Property, value); }
        }

        private static void OnFileImageViewModel1PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CompareImagesView source = d as CompareImagesView;
            FileImageViewModel v = e.NewValue as FileImageViewModel;
            FileImageViewModel vOld = e.OldValue as FileImageViewModel;

            if (v != vOld)
            {
                source.UpdateFileImageViewModel1(v, vOld);
            }
        }

        private static void OnFileImageViewModel2PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CompareImagesView source = d as CompareImagesView;
            FileImageViewModel v = e.NewValue as FileImageViewModel;
            FileImageViewModel vOld = e.OldValue as FileImageViewModel;

            if (v != vOld)
            {
                source.UpdateFileImageViewModel2(v, vOld);
            }
        }

        private void UpdateFileImageViewModel1(FileImageViewModel viewModel, FileImageViewModel old)
        {
            if (old != null)
            {
                old.SuspendUnload = false;
            }

            viewModel.SuspendUnload = true;
            FileImageViewModel1 = viewModel;            

            if (!FileImageViewModel1.BitmapImageLoaded)
            {
                FileImageViewModel1.DataLoaded += new EventHandler<ObjectEventArgs<string>>(viewModel1_DataLoaded);
                FileImageViewModel1.LoadBitmap();
            }
            else
            {
                DoBinding1();
            }
        }

        void viewModel1_DataLoaded(object sender, ObjectEventArgs<string> e)
        {
            var vm = sender as FileImageViewModel;
            vm.DataLoaded -= viewModel1_DataLoaded;
            DoBinding1();
        }

        void viewModel2_DataLoaded(object sender, ObjectEventArgs<string> e)
        {
            var vm = sender as FileImageViewModel;
            vm.DataLoaded -= viewModel2_DataLoaded;
            DoBinding2();
        }

        public void DoBinding1()
        {
            Binding b = new Binding() { Path = new PropertyPath("BitmapImage") };            
            imgMain1.SetBinding(Image.SourceProperty, b);
            imgMain1.DataContext = FileImageViewModel1;
            imgMain1.InvalidateVisual();
        }

        public void DoBinding2()
        {
            Binding b = new Binding() { Path = new PropertyPath("BitmapImage") };            
            imgMain2.SetBinding(Image.SourceProperty, b);
            imgMain2.DataContext = FileImageViewModel2;
            imgMain2.InvalidateVisual();
        }

        private void UpdateFileImageViewModel2(FileImageViewModel viewModel, FileImageViewModel old)
        {
            if (old != null)
            {
                old.SuspendUnload = false;
            }

            viewModel.SuspendUnload = true;
            FileImageViewModel2 = viewModel;

            if (!FileImageViewModel2.BitmapImageLoaded)
            {
                FileImageViewModel2.DataLoaded += new EventHandler<ObjectEventArgs<string>>(viewModel2_DataLoaded);
                FileImageViewModel2.LoadBitmap();
            }
            else
            {
                DoBinding2();
            }
        }

        public CompareImagesView()
        {
            InitializeComponent();
        }

        private void btnDuplicate_Click(object sender, RoutedEventArgs e)
        {
            if (Duplicate != null)
                Duplicate(this, new ObjectEventArgs<FileImageViewModel, FileImageViewModel>(FileImageViewModel1, FileImageViewModel2));
        }

        private void btnNotDuplicate_Click(object sender, RoutedEventArgs e)
        {
            if (NotDuplicate != null)
                NotDuplicate(this, new ObjectEventArgs<FileImageViewModel, FileImageViewModel>(FileImageViewModel1, FileImageViewModel2));
        }

        private void btnAllDuplicates_Click(object sender, RoutedEventArgs e)
        {
            if (AllDuplicates != null)
                AllDuplicates(this, new ObjectEventArgs<FileImageViewModel, FileImageViewModel>(FileImageViewModel1, FileImageViewModel2));
        }
    }
}
